package de.mindshareprojects.datawarehouse.client;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;

import com.google.gwt.core.client.EntryPoint;
import com.google.gwt.core.client.GWT;
import com.google.gwt.event.dom.client.ChangeEvent;
import com.google.gwt.event.dom.client.ChangeHandler;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.i18n.client.DateTimeFormat;
import com.google.gwt.user.client.Cookies;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.Anchor;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.DecoratedTabPanel;
import com.google.gwt.user.client.ui.FlexTable;
import com.google.gwt.user.client.ui.HTML;
import com.google.gwt.user.client.ui.HorizontalPanel;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.ListBox;
import com.google.gwt.user.client.ui.RootPanel;
import com.google.gwt.user.client.ui.TextArea;

import de.mindshareprojects.datawarehouse.shared.Advertiser;
import de.mindshareprojects.datawarehouse.shared.Campaign;
import de.mindshareprojects.datawarehouse.shared.WebAnalyticsLineItem;

/**
 * Entry point classes define <code>onModuleLoad()</code>.
 */
public class DataWarehouse implements EntryPoint {
	/**
	 * Create necessary login items
	 */
	
	protected static LoginInfo loginInfo = null;
	
	// invoke data service
	private final static DataServiceAsync dataService = GWT.create(DataService.class);
	
	/** create GUI elements
	 * 
	 */
	private HorizontalPanel hpLoginPanel = new HorizontalPanel();
	private Label loginLabel = new Label("Please sign in to your mindshareprojects.de account to access this application.");
	private Anchor signInLink = new Anchor("Sign In");
	private Anchor signOutLink = new Anchor("Sign Out");
	
	private HorizontalPanel hpLogoutPanel = new HorizontalPanel();
	
	public static DecoratedTabPanel mainPanel = new DecoratedTabPanel();
	public static Label systemMessages = new Label();
	
	public static HorizontalPanel hpCountry = new HorizontalPanel();
	public static ListBox lbCountrySelection = new ListBox();
	public static ListBox lbAdvertiser = new ListBox();
	private static HorizontalPanel hpDebugPanel = new HorizontalPanel();
	private static Button bShowAdvertisers = new Button("Advertisers");
	private static Button bShowCampaigns = new Button("Campaigns");
	private static Button bShowWALineItems = new Button("Web Analytics");
	private static Button bClearLog = new Button("Clear");

	public static TextArea debugOutput = new TextArea();
	public static FlexTable ftShowData = new FlexTable();
	
	public static HashMap<Long, Advertiser> advertiserLookUp = new HashMap<Long, Advertiser>();
	public static HashMap<String, Advertiser> advertiserDAPLookUp = new HashMap<String, Advertiser>();
	public static HashMap<Long, String> advertiserGroupWebAnalytics = new HashMap<Long, String>();
	
	public static String selectedCountry = "";
	private static Label countryLabel = new Label();
	
    final ChangeHandler changeCountry = new ChangeHandler() {
    	
    	@Override
    	public void onChange(ChangeEvent event) {
			mainPanel.setVisible(true);
    		lbCountrySelection.setVisible(false);
    		selectedCountry = lbCountrySelection.getItemText(lbCountrySelection.getSelectedIndex());
    		countryLabel.setText(selectedCountry);
    		countryLabel.setVisible(true);
    		dataSetup();
    		Cookies.setCookie("country", selectedCountry);		
    	}
    };

    final ClickHandler clickCountryToggle = new ClickHandler() {
		
		@Override
		public void onClick(ClickEvent event) {
			lbCountrySelection.setVisible(true);
			countryLabel.setVisible(false);
		}
	};

    
	
	
	/** formatting elements
	 * 
	 */
	private static DateTimeFormat dateFormatMed = DateTimeFormat.getMediumDateTimeFormat();

	
	/**
	 * This is the entry point method.
	 */
	public void onModuleLoad() {

	    // Check login status using login service.
	    RootPanel.get("messagePanel").add(systemMessages);
		LoginServiceAsync loginService = GWT.create(LoginService.class);
	    loginService.login(GWT.getHostPageBaseURL(), new AsyncCallback<LoginInfo>() {
	      public void onFailure(Throwable error) {
	      }

	      public void onSuccess(LoginInfo result) {
	        loginInfo = result;
	        if(loginInfo.isLoggedIn()) {
	        	loadFrontEnd();
	        } else {
	          loadLogin();
	        }
	      }
	    });
	  }

	  private void loadLogin() {
	    // Assemble login panel.
	    signInLink.setHref(loginInfo.getLoginUrl());
	    hpLoginPanel.add(loginLabel);
	    hpLoginPanel.add(new Label(" "));
	    hpLoginPanel.add(signInLink);
	    RootPanel.get("loginScreen").insert(hpLoginPanel, 0);
	  }

	private void loadFrontEnd() {
		
	    mainPanel.setVisible(false);
		// Set up sign out hyperlink.
	    signOutLink.setHref(loginInfo.getLogoutUrl());
	    
	    // compose logout and country selection
	    lbCountrySelection.addItem("--", "--");
	    lbCountrySelection.addItem("AT", "AT");
	    lbCountrySelection.addItem("CH", "CH");
	    lbCountrySelection.addItem("DE", "DE");
	    
	    hpCountry.add(new Label("Please select your country: "));
	    hpCountry.add(lbCountrySelection);
	    hpCountry.add(countryLabel);
	    countryLabel.setVisible(false);
	    
	    // add change handler to country dropbox
	    lbCountrySelection.addChangeHandler(changeCountry);
	    
	    // add click handler to country label
	    countryLabel.addClickHandler(clickCountryToggle);
	    
	    // Check if country is stored in cookie
	    try {
	    	if(!(Cookies.getCookie("country").isEmpty() && Cookies.getCookie("country").equals(null))){
	    		int index = 0;
	    		for(index = 0; index < lbCountrySelection.getItemCount(); index++){
	    			
	    			if(Cookies.getCookie("country").equals(lbCountrySelection.getItemText(index))){
	    				selectedCountry = Cookies.getCookie("country");
	    				lbCountrySelection.setItemSelected(index, true);
	    				lbCountrySelection.setVisible(false);
	    				countryLabel.setText(selectedCountry);
	    				countryLabel.setVisible(true);
	    				mainPanel.setVisible(true);
	    				System.out.println("Country read from Cookie: " + selectedCountry);
	    				dataSetup();
	    			}
	    		}
	    	}
			
		} catch (Exception e) {
			System.out.println("No cookie found for parameter country");
		}

		// set up logout panel
	    hpLogoutPanel.add(signOutLink);
	    hpLogoutPanel.add(new HTML("&nbsp;&nbsp;"));
	    hpLogoutPanel.add(new Label(" Hello " + loginInfo.getNickname()+ "! "));
	    hpLogoutPanel.add(hpCountry);
	    
	    RootPanel.get("logoutScreen").add(hpLogoutPanel);
	    
	    // set up navigational frame to insert modules
	    mainPanel.add(CampaignIds.campaignIdPanel(), "Advertisers & Campaigns");
	    mainPanel.add(WebAnalytics.webAnalyticsPanel(), "Web Analytics");
	    mainPanel.setWidth("100%");
	    
	    //<-- check for admin privileges and add admin panel
	    
	    if(loginInfo.isAdmin() == true){
	    	mainPanel.add(AdminPanel.adminPanel(), "Admin");
		    RootPanel.get("debugOutput").add(hpDebugPanel);
		    RootPanel.get("debugOutput").add(debugOutput);
		    debugOutput.setVisibleLines(50);
		    debugOutput.setPixelSize(1000, 300);

	    }
	    
	    // -->
	    
	    // add click handler to debug panel buttons
	    bShowAdvertisers.addClickHandler(new ClickHandler() {
			
			@Override
			public void onClick(ClickEvent event) {
				dataService.getAdvertisersByCountry(selectedCountry, new AsyncCallback<ArrayList<Advertiser>>() {

					@Override
					public void onFailure(Throwable caught) {
						// TODO Auto-generated method stub
						System.out.println("RPC failure in DataWarehouse.java: dataService.getAdvertisers()");
					}

					@Override
					public void onSuccess(ArrayList<Advertiser> result) {
						DataWarehouse.log(result.size() + " advertisers in database:");
						for(Advertiser a: result){
							DataWarehouse.log("Advertiser "+ a.getCountry() + ": " + a.getKey() + " " + a.getAdvertiserName()+ "[" + a.getForeignKey() + "]");
						}
					}
				});
				
			}
		});
	    bShowCampaigns.addClickHandler(new ClickHandler() {
			
			@Override
			public void onClick(ClickEvent event) {
				dataService.getCampaigns(new AsyncCallback<ArrayList<Campaign>>() {

					@Override
					public void onFailure(Throwable caught) {
						log("RPC failure in DataWarehouse.java: dataService.getCampaigns()");
						
					}

					public void onSuccess(ArrayList<Campaign> result) {
						DataWarehouse.log(result.size() + " campaigns in database:");
						for (Campaign c: result){
							DataWarehouse.log("Campaign: " + c.getKey() + " " + c.getCampaignName() + " [" + c.getAdvertiserName() + ", " + c.getAdvertiserId() + "]");
						}
						
					}
				});
				
			}
		});
	    bShowWALineItems.addClickHandler(new ClickHandler() {
	    	
	    	@Override
	    	public void onClick(ClickEvent event) {
	    		Long groupKey = Long.parseLong("1");
	    		dataService.getWebAnalyticsLineItemsByAdvertiserGroup(groupKey, new AsyncCallback<ArrayList<WebAnalyticsLineItem>>() {

					@Override
					public void onFailure(Throwable caught) {
						// TODO Auto-generated method stub
						
					}

					@Override
					public void onSuccess(ArrayList<WebAnalyticsLineItem> result) {
						DataWarehouse.log("This is just the result for groupKey = 1 which is Unilever!");
						for (WebAnalyticsLineItem wali: result) {
							DataWarehouse.log(wali.getCountry() + " item " + wali.getKey() + ":" +
									"Campaign: " + wali.getCampaignKey() +
									"|Creative: " + wali.getCreative() +
									"|Creative Type: " + wali.getCreativeType() +
									"|Demand Channel: " + wali.getDemandChannel() +
									"|Description: " + wali.getDescription() +
									"|Marketing Activity: " + wali.getMarketingActivity() +
									"|Marketing Program: " + wali.getMarketingProgram() +
									"|Search: " + wali.getSearch() + "\r"
									);
						}
						
					}
				});
	    	}
	    	
	    });
			
	    
	    bClearLog.addClickHandler(new ClickHandler() {
			
			@Override
			public void onClick(ClickEvent event) {
				debugOutput.setText("");
			}
		});
	    
	    // compose debug panel
	    hpDebugPanel.add(bShowAdvertisers);
	    hpDebugPanel.add(bShowCampaigns);
	    hpDebugPanel.add(bShowWALineItems);
	    hpDebugPanel.add(bClearLog);
	    
	    
	    
	    // compose root panel
	    RootPanel.get("mainContent").add(mainPanel);
	    RootPanel.get("mainContent").add(new HTML("<br>"));
	    RootPanel.get("mainContent").add(ftShowData);
	    
	    
	    mainPanel.selectTab(0);
	}
	
	/**
	 * Sets up initial data needed by more than one module.
	 * Currently queried classes: 
	 * Advertiser -> populated to public ListBox lbAdvertiser
	 */
	public static void dataSetup() {
		// get advertisers from server
		dataService.getAdvertisersByCountry(selectedCountry, new AsyncCallback<ArrayList<Advertiser>>() {

			@Override
			public void onFailure(Throwable caught) {
				DataWarehouse.log("Error: Advertisers could not be fetchd from server.");
				
			}
			// on success populate advertisers to dropdown
			public void onSuccess(ArrayList<Advertiser> result) {
				// clear fields & maps
				WebAnalytics.lbCampaign.clear();
				WebAnalytics.lbCampaign.addItem("--", "--");
				WebAnalytics.lbAdvertiser.clear();
				WebAnalytics.lbAdvertiser.addItem("--", "--");
				CampaignIds.lbAdvertiser.clear();
				CampaignIds.lbAdvertiser.addItem("--", "--");
				advertiserDAPLookUp.clear();
				advertiserLookUp.clear();
				// fill in advertisers to advertiser dropdown and groups to group dropdown
				
				for (Advertiser a: result){
					CampaignIds.lbAdvertiser.addItem(a.getAdvertiserName(), a.getKey().toString());
					advertiserDAPLookUp.put(a.getForeignKey(), a);
					advertiserLookUp.put(a.getKey(), a);
					if(a.getWebAnalytics() == true && !(a.getAdvertiserGroupKey() == null)){
						advertiserGroupWebAnalytics.put(a.getAdvertiserGroupKey(), a.getAdvertiserGroupName());
						System.out.println("Group added to WA Advertiser ListBox");
					}
				}
				for(Long key: advertiserGroupWebAnalytics.keySet()){
					WebAnalytics.lbAdvertiser.addItem(DataWarehouse.advertiserGroupWebAnalytics.get(key), key.toString());
				}
			}
		});
	}

	/**
	 * Global debug function, logging to TextArea in RootPanel
	 * @param debugInfo debug information as String
	 */
	public static void log(String debugInfo) {
		Date now = new Date();
		
		debugOutput.setText(debugOutput.getText() + "\r" + dateFormatMed.format(now) + " "+ debugInfo);
	}
	
	
}
